﻿using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using Active.Core;
using Active.Core.State;
using System.Text;
using Csla.Validation;

public partial class Bill_MediaOrders : System.Web.UI.Page
{
    private enum Views
    {
        MainView = 0,
        EditMediaOrderView = 1
    }

    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            ApplyAuthorizationRules();
        }
    }

    private void ApplyAuthorizationRules()
    {
        Order obj = GetOrder();
        if (MediaOrder.CanAddObject())
        {
            if (obj.MediaOrders.Count == 0)
            {
                this.MultiView1.ActiveViewIndex = (int)Views.EditMediaOrderView;
                this.MediaOrderDetailsView.DefaultMode = DetailsViewMode.Insert;
            }
        }
        this.lbtnAddMediaOrder.Visible = CanEdit();

        this.phOperations.Visible = obj.CanConfirm() || obj.CanCancelConfirmed();
        if (this.phOperations.Visible)
        {
            this.phSubmitBill.Visible = obj.CanConfirm();
            this.btnCancelConfirmBill.Visible = obj.CanCancelConfirmed();

            if (this.phSubmitBill.Visible) //若可提交
            {
                bool hadPay = obj.DeductFromAdvance > 0 || obj.DeductFromBrokerage > 0;
                this.btnClearPay.Visible = hadPay;
                //先尝试全部从预付款中扣除
                decimal advance = decimal.Zero, brokerage = decimal.Zero;
                if (!hadPay)
                {
                    if (obj.Media.Advance > 0)
                    {
                        advance = obj.Payout;
                        if ((obj.Media.Advance - advance) < 0) //若预付款不够, 则尝试将剩余的从返点中扣除
                        {
                            advance = obj.Media.Advance;

                            if (obj.Media.Brokerage > 0)
                            {
                                brokerage = obj.Payout - advance;
                                if ((obj.Media.Brokerage - brokerage) < 0) //若仍然不够, 则尽可能多地支付
                                {
                                    brokerage = obj.Media.Brokerage;
                                }
                            }
                        }
                    }
                }
                this.phSubmitPayInfo.Visible = !hadPay;
                this.txtDeductFromAdvance.Text = advance.ToString("f2");
                this.txtDeductFromBrokerage.Text = brokerage.ToString("f2");
            }
        }

        this.plMediaDescription.Visible = this.phOperations.Visible && Utils.IsMediaEmployee;
        if (this.plMediaDescription.Visible)
        {
            this.txtOrderMediaDescription.Text = obj.MediaDescription;
        }

        if (obj.StateValue != StateValue.MediaEmployeeWorking)
        {
            this.MediaOrdersRepeater.Visible = false;
            this.mediaBill.Visible = true;
        }
    }

    protected bool CanEdit()
    {
        Order obj = GetOrder();
        return MediaOrder.CanAddObject() && obj.StateValue == StateValue.MediaEmployeeWorking;
    }

    protected void lbtnAddMediaOrder_Click(object sender, EventArgs e)
    {
        this.MultiView1.ActiveViewIndex = (int)Views.EditMediaOrderView;
        this.MediaOrderDetailsView.DefaultMode = DetailsViewMode.Insert;
    }

    protected void btnSubmitBill_Click(object sender, EventArgs e)
    {
        Order obj = GetOrder();
        obj.MediaDescription = txtOrderMediaDescription.Text;
        obj.DeductFromAdvance = decimal.Parse(txtDeductFromAdvance.Text);
        obj.DeductFromBrokerage = decimal.Parse(txtDeductFromBrokerage.Text);
        obj.Confirm();
        Response.Redirect(Request.RawUrl, true);
    }

    protected void btnClearPay_Click(object sender, EventArgs e)
    {
        Order obj = GetOrder();
        obj.ClearPayInfo();
        Response.Redirect(Request.RawUrl, true);
    }

    protected void btnSubmitPayInfo_Click(object sender, EventArgs e)
    {
        Order obj = GetOrder();
        obj.DeductFromAdvance = decimal.Parse(this.txtDeductFromAdvance.Text);
        obj.DeductFromBrokerage = decimal.Parse(this.txtDeductFromBrokerage.Text);
        obj.SubmitPayInfo();
        Response.Redirect(Request.RawUrl, true);
    }

    protected void btnCancelConfirmBill_Click(object sender, EventArgs e)
    {
        GetOrder().CancelConfirmed();
        Response.Redirect("~/Bill/OrderList.aspx", true);
    }

    protected void lbtnReturn_Click(object sender, EventArgs e)
    {
        Order order = GetOrder();
        if (order.MediaOrders.Count == 0)
        {
            Response.Redirect("~/Bill/OrderList.aspx", true);
        }
        Response.Redirect(Request.RawUrl, true);
    }

    #region Business Methods

    protected Order GetOrder()
    {
        string idString = Request.QueryString["id"];
        object businessObj = Session["CurrentObj"];
        if (businessObj == null || !(businessObj is Order)
            || (!IsPostBack && !((Order)businessObj).Id.ToString().Equals(idString)))
        {
            try
            {
                if (!string.IsNullOrEmpty(idString))
                {
                    businessObj = Order.GetOrder(int.Parse(idString));
                }
                else
                {
                    Response.Redirect("~/Bill/OrderList.aspx");
                }
                Session["CurrentObj"] = businessObj;
            }
            catch (System.Security.SecurityException)
            {
                Response.Redirect("~/Bill");
            }
        }
        return businessObj as Order;
    }

    private MediaOrder _mediaOrder;
    private MediaOrder GetMediaOrder()
    {

        return _mediaOrder;
    }

    private int SaveOrder(Order obj)
    {
        int rowsAffected = 0;
        try
        {
            Session["CurrentObj"] = obj.Save();
            rowsAffected = 1;
        }
        catch (Csla.Validation.ValidationException ex)
        {
            throw ex;
        }
        catch (Csla.DataPortalException ex)
        {
            throw ex;
        }
        catch (Exception ex)
        {
            throw ex;
        }
        return rowsAffected;
    }

    #endregion

    #region MediaOrdersRepeater
    protected int Colspan1
    {
        get
        {
            Order obj = GetOrder();
            return DateTime.DaysInMonth(obj.Bill.StartDate.Date.Year, obj.Bill.StartDate.Date.Month)
                - obj.Bill.StartDate.Date.Day + 1;
        }
    }
    protected int Colspan2
    {
        get
        {
            Order obj = GetOrder();
            return obj.Bill.StartDate.Date.AddMonths(1).Day;
        }
    }
    protected string MonthsHeader
    {
        get
        {
            Order obj = GetOrder();
            return string.Format("<th colspan='{0}'>{1}</th><th colspan='{2}'>{3}</th>",
                Colspan1, obj.Bill.StartDate.ToString("M月"),
                Colspan2, obj.Bill.StartDate.Date.AddMonths(1).ToString("M月"));
        }
    }

    protected string DaysHeader
    {
        get
        {
            Order obj = GetOrder();
            return Formater.GetCampaignPeriodDaysHTML(obj.Bill.StartDate.Date,
                obj.Bill.StartDate.Date.AddMonths(1));
        }
    }

    private static readonly string CampaignPeriodTd =
        "<td><span class='block'>{0}</span><span class='block'>{1}</span></td>";
    protected string FormatCampaignPeriodHTML(string campaignPeriodString)
    {
        if (string.IsNullOrEmpty(campaignPeriodString))
        {
            return string.Empty;
        }
        StringBuilder sb = new StringBuilder(31);
        string[] cps = campaignPeriodString.Split('|');
        foreach (string cp in cps)
        {
            sb.AppendFormat(CampaignPeriodTd,
                cp.Substring(0, 1) == "0" ? "" : cp.Substring(0, 1), cp.Substring(1, 1));
        }
        return sb.ToString();
    }

    protected void MediaOrdersRepeater_ItemCommand(object source, RepeaterCommandEventArgs e)
    {
        if (e.CommandName == "Edit")
        {
            Order order = GetOrder();
            _mediaOrder = order.MediaOrders.GetMediaOrderById(int.Parse(e.CommandArgument.ToString()));
            SelectedCustomerOrderId = _mediaOrder.CustomerOrderId;
            this.MultiView1.ActiveViewIndex = (int)Views.EditMediaOrderView;
            this.plEditMediaOrderForm.Visible = true;
            this.MediaOrderDetailsView.DefaultMode = DetailsViewMode.Edit;
        }
        else if (e.CommandName == "Delete")
        {
            Order order = GetOrder();
            order.MediaOrders.Remove(int.Parse(e.CommandArgument.ToString()));
            SaveOrder(order);
            Response.Redirect(Request.RawUrl, true);
        }
    }

    //decimal _totalPayout = 0m;
    //decimal _totalRealPayout = 0m;
    int _totalTimes = 0;

    protected void MediaOrdersRepeater_ItemDataBound(object sender, RepeaterItemEventArgs e)
    {
        if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
        {
            MediaOrder mediaOrder = e.Item.DataItem as MediaOrder;
            //_totalPayout += mediaOrder.Payout;
            if (mediaOrder.Category != OrderType.Additional)
            {
                _totalTimes += mediaOrder.Times;
            }

        }
        if (e.Item.ItemType == ListItemType.Footer)
        {
            HtmlTableRow tr = e.Item.FindControl("TotalCaculateFooter") as HtmlTableRow;
            HtmlTableCell tdTotalName = new HtmlTableCell();
            tdTotalName.ColSpan = Colspan1 + Colspan2 + (GetOrder().Media.Category == MediaType.TV ? 6 : 4);
            tdTotalName.Attributes["class"] = "right";
            tdTotalName.InnerHtml = "合  计:";
            tr.Controls.Add(tdTotalName);

            Order obj = GetOrder();
            HtmlTableCell tdTotalTimes = new HtmlTableCell();
            tdTotalTimes.Attributes["class"] = "right";
            tdTotalTimes.InnerHtml = _totalTimes.ToString();
            tr.Controls.Add(tdTotalTimes);

            HtmlTableCell tdTotalFinalPayout = new HtmlTableCell();
            tdTotalFinalPayout.ColSpan = 3;
            tdTotalFinalPayout.Attributes["class"] = "right";
            tdTotalFinalPayout.InnerHtml = Formater.FormatMoney(obj.Payout);
            tr.Controls.Add(tdTotalFinalPayout);
        }
    }

    #endregion

    #region MediaOrdersDataSource

    protected void MediaOrdersDataSource_SelectObject(object sender, Csla.Web.SelectObjectArgs e)
    {
        e.BusinessObject = GetOrder().MediaOrders;
    }

    #endregion

    #region CustomerOrdersRepeater

    protected void CustomerOrdersRepeater_ItemCommand(object source, RepeaterCommandEventArgs e)
    {
        if (e.CommandName == "Select")
        {
            foreach (RepeaterItem item in CustomerOrdersRepeater.Items)
            {
                if (item.ItemType == ListItemType.Item || item.ItemType == ListItemType.AlternatingItem)
                {
                    LinkButton lbtn = item.FindControl("SelectLinkButton") as LinkButton;
                    if (item.ItemIndex == e.Item.ItemIndex)
                    {
                        lbtn.CssClass = "selected";
                        SelectedCustomerOrderId = int.Parse(e.CommandArgument.ToString());
                        lbtn.Enabled = false;
                    }
                    else
                    {
                        lbtn.CssClass = "";
                        lbtn.Enabled = true;
                    }
                }
            }

            this.plEditMediaOrderForm.Visible = true;
            CustomerOrder custOrder = 
                GetOrder().CustomerOrders.GetCustomerOrderById(int.Parse(e.CommandArgument.ToString()));
            CampaignPeriodControl cpc =
            MediaOrderDetailsView.FindControl("CampaignPeriodControl1") as CampaignPeriodControl;
            cpc.CampaignPeriodString = custOrder.CampaignPeriod;
            DropDownList ddlOrderType = MediaOrderDetailsView.FindControl("ddlOrderType") as DropDownList;
            ddlOrderType.SelectedValue = custOrder.Category.ToString();
            DropDownList ddlChannels = MediaOrderDetailsView.FindControl("ddlChannels") as DropDownList;
            ddlChannels.SelectedValue = custOrder.Channel;
            TextBox txtTimeSlot = MediaOrderDetailsView.FindControl("txtTimeSlot") as TextBox;
            txtTimeSlot.Text = custOrder.TimeSlot;
            TextBox txtPosition = MediaOrderDetailsView.FindControl("txtPosition") as TextBox;
            txtPosition.Text = custOrder.Position;
            TextBox txtDuration = MediaOrderDetailsView.FindControl("txtDuration") as TextBox;
            txtDuration.Text = custOrder.Duration;
        }
    }

    protected void CustomerOrdersRepeater_ItemDataBound(object sender, RepeaterItemEventArgs e)
    {
        RepeaterItem item = e.Item;
        if (item.ItemType == ListItemType.Item || item.ItemType == ListItemType.AlternatingItem)
        {
            if (_mediaOrder != null)
            {
                LinkButton lbtn = item.FindControl("SelectLinkButton") as LinkButton;
                if (item.DataItem.ToString() == _mediaOrder.CustomerOrderId.ToString())
                {
                    lbtn.CssClass = "selected";
                }
                else
                {
                    lbtn.CssClass = "";
                }
            }
        }
    }

    #endregion

    #region CustomerOrdersDataSource

    protected void CustomerOrdersDataSource_SelectObject(object sender, Csla.Web.SelectObjectArgs e)
    {
        e.BusinessObject = GetOrder().CustomerOrders;
    }

    #endregion

    private int SelectedCustomerOrderId
    {
        get 
        {
            return (int)ViewState["SelectedCustomerOrderId"];
        }
        set
        {
            ViewState["SelectedCustomerOrderId"] = value;
        }
    }

    #region MediaOrderDataSource

    protected void MediaOrderDataSource_SelectObject(object sender, Csla.Web.SelectObjectArgs e)
    {
        e.BusinessObject = _mediaOrder;
    }

    protected void MediaOrderDataSource_InsertObject(object sender, Csla.Web.InsertObjectArgs e)
    {
        Order order = GetOrder();
        MediaOrder mediaOrder = order.MediaOrders.AddNew();
        mediaOrder.CustomerOrderId = SelectedCustomerOrderId;
        Caculate(mediaOrder, e.Values);
        //Csla.Data.DataMapper.Map(e.Values, mediaOrder);
        //mediaOrder.Discount = mediaOrder.Discount / 100;
        e.RowsAffected = SaveOrder(order);
        Response.Redirect(Request.RawUrl, true);
        
    }

    protected void MediaOrderDataSource_UpdateObject(object sender, Csla.Web.UpdateObjectArgs e)
    {
        Order order = GetOrder();
        MediaOrder mediaOrder = order.MediaOrders.GetMediaOrderById((int)e.Keys["Id"]);
        mediaOrder.CustomerOrderId = SelectedCustomerOrderId;
        Caculate(mediaOrder, e.Values);
        //e.Values["Discount"] = e.Values["Discount"].ToString().Replace("%", "");
        //Csla.Data.DataMapper.Map(e.Values, mediaOrder);
        //mediaOrder.Discount = mediaOrder.Discount / 100;
        //CampaignPeriodControl cpc = 
        //    MediaOrderDetailsView.FindControl("CampaignPeriodControl1") as CampaignPeriodControl;
        //mediaOrder.CampaignPeriod = cpc.CampaignPeriodString;
        e.RowsAffected = SaveOrder(order);
        Response.Redirect(Request.RawUrl, true);
    }

    private void Caculate(MediaOrder mediaOrder, IDictionary values)
    {
        values["Discount"] = values["Discount"].ToString().Replace("%", "");
        Csla.Data.DataMapper.Map(values, mediaOrder);
        mediaOrder.Discount = mediaOrder.Discount / 100;
        CampaignPeriodControl cpc =
            MediaOrderDetailsView.FindControl("CampaignPeriodControl1") as CampaignPeriodControl;
        mediaOrder.Times = cpc.TotalTimes;
        mediaOrder.CampaignPeriod = cpc.CampaignPeriodString;

        switch (mediaOrder.Category)
        {
            case OrderType.Additional:
                mediaOrder.Payout = mediaOrder.UnitPrice * mediaOrder.Times;
                mediaOrder.Times = 0;
                mediaOrder.Discount = 0;
                break;
            case OrderType.Pay:
                mediaOrder.Payout = mediaOrder.UnitPrice * mediaOrder.Times * (decimal)(1 - mediaOrder.Discount);
                break;
            default:
                mediaOrder.Payout = 0;
                mediaOrder.Discount = 0;
                break;
        }
    }

    #endregion

    #region MediaOrderDetailsView and it's child controls
    protected void MediaOrderDetailsView_DataBound(object sender, EventArgs e)
    {
        Order order = GetOrder();
        if (order.Media.Category == MediaType.Publication)
        {
            this.MediaOrderDetailsView.Rows[1].Visible = false;
            this.MediaOrderDetailsView.Rows[2].Visible = false;
        }

        CampaignPeriodControl cpc =
            MediaOrderDetailsView.FindControl("CampaignPeriodControl1") as CampaignPeriodControl;
        cpc.StartDate = order.Bill.StartDate.Date;
        cpc.VersionsCount = order.PlayVersions != null ? order.PlayVersions.Length : 0;
        cpc.DataBind();

        if (_mediaOrder != null)
        {
            cpc.CampaignPeriodString = _mediaOrder.CampaignPeriod;
        }
    }

    protected void MediaOrderDetailsView_ItemCommand(object sender, DetailsViewCommandEventArgs e)
    {
        if (e.CommandName == "Cancel")
        {
            Response.Redirect(Request.RawUrl, true);
        }
    }

    #endregion


    
}
